package www.com.zhongge.stack;

import java.util.Arrays;

/**
 * @ClassName MyStackOfArray
 * @Description TODO 使用数组实现栈
 * @Author 笨忠
 * @Date 2025/7/26 15:24
 * @Version 1.0
 */
@SuppressWarnings("all")
public class MyStackOfArray<T> {
    //需要一个数组
    private Object[] array;
    //使用usedSize标记元素个数和元素下标==》顺序表必备的
    private int usedSize;
    public MyStackOfArray(){
        //只需初始化数组即可，因为usedSize默认是0
        array = new Object[5];//默认大小为5
    }

    /**
     * 入栈操作
     * @param e 元素值
     * @return 返回所入得值（根据需求设计）
     */
    public T push(T e){
        //无论什么数据结构在插入之前都得知道==》是否可以放元素==》即扩容
        if (empty()){
            //如果满了就扩容==>二倍扩容
            ensureCapacity();
        }
        //进行入栈：两步骤==》将元素放入当前的usedSize下标处，然后再usedSize++
        array[usedSize] = e;
        usedSize++;
        return e;
    }

    /**
     * 出栈
     * @return 栈顶元素值
     */
    public T pop(){
        //判断是否为空==>无论什么数据结构你那元素都要看是不是为空
        if (empty()) {
            throw new EmptyElementException("栈中没有元素了");
        }
        //程序能够走到这里说明元素没有空
        return (T)array[--usedSize];
    }

    /**
     * 取出栈顶元素
     * @return
     */
    public T peek(){
        if (empty()) {
            throw new EmptyElementException("栈中没有元素了");
        }
        return (T)array[usedSize - 1];//为什么-1：因为usedSize始终指向最后一个元素的下一个
    }

    /**
     * 栈中的元素个数
     * @return
     */
    public int size(){
        return usedSize;
    }

    /**
     * 栈是否为空
     * @return
     */
    public boolean empty(){
        return usedSize == 0;//这个方法在顺序表中是最常用的
    }

    /**
     * 确保容量
     */
    private void ensureCapacity(){
        //改方法会返回一个新的地址
        this.array = Arrays.copyOf(this.array, this.array.length *2);
    }
}
